﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using Basic4Net.Entities;
using Microsoft.Data.Extensions;

namespace Basic4Net.BusinessRules
{
    public class Amount : BaseBR
    {
        /// <summary>
        /// 获取当前核算月
        /// </summary>
        /// <returns></returns>
        public t_Amount GetActiveAmount(string schoolMark)
        {
            DBEntities db;
            using (db = new DBEntities())
            {
                var list = (from a in db.t_Amount
                            where a.FPlan == 1 && a.SchoolMark == schoolMark
                            select a);

                t_Amount res = list.FirstOrDefault();

                return res;
            }
        }

        /// <summary>
        /// 获取当前核算月
        /// </summary>
        /// <returns></returns>
        public IList<t_Amount> GetAllActiveAmount(string schoolMark)
        {
            DBEntities db;
            using (db = new DBEntities())
            {
                var list = (from a in db.t_Amount
                            where a.FPlan == 1 && a.SchoolMark == schoolMark
                            select a);

                IList<t_Amount> res = list.ToList();

                return res;
            }
        }

        /// <summary>
        /// 更新拨款金额
        /// </summary>
        /// <param name="appType">金额类型</param>
        /// <param name="year">年份</param>
        /// <param name="month">月份</param>
        /// <param name="money">金额</param>
        /// <param name="schoolMark">schoolMark</param>
        /// <returns></returns>
        public bool UpdateAmount(int appType, int year, int month, double money, string schoolMark)
        {
            DBEntities db;
            using (db = new DBEntities())
            {
                var list = (from a in db.t_Amount
                            where a.FPlan == 1 && a.SchoolMark == schoolMark && a.AppType == appType
                            select a);

                var at = list.FirstOrDefault();
                if (at == null)
                    return false;

                at.AppAmount = money;
                db.t_Amount.ApplyCurrentValues(at);
                try
                {
                    db.SaveChanges();
                }
                catch (Exception)
                {
                    return false;
                }

                return true;
            }
        }

        /// <summary>
        /// 更新当前月信息
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <param name="schoolMark"></param>
        /// <returns></returns>
        public bool CreateOrUpdate(int year, int month, int holType, string schoolMark)
        {
            DBEntities db;
            using (db = new DBEntities())
            {
                var list = (from a in db.t_Amount
                            where a.FPlan == 1 && a.SchoolMark == schoolMark
                            select a);

                var current = list.FirstOrDefault(p => p.AppType == 1);
                if (current != null)
                {
                    if (current.FMonth == month && current.FYear == year && current.HolType == holType)
                        return true;

                    current.FPlan = 0;
                    db.t_Amount.ApplyCurrentValues(current);

                    current = list.FirstOrDefault(p => p.AppType == 2);
                    current.FPlan = 0;
                    db.t_Amount.ApplyCurrentValues(current);

                }

                var newlist = (from b in db.t_Amount
                               where b.FYear == year && b.FMonth == month && b.SchoolMark == schoolMark
                               select b);

                var lastTerm = (from t in db.TermInfo
                                where t.SchoolMark == schoolMark
                                orderby t.StartDate descending
                                select t).FirstOrDefault();


                var newAmount = newlist.FirstOrDefault(p => p.AppType == 1);
                if (newAmount == null)
                {
                    var t0 = new t_Amount { FYear = year, FMonth = month, FPlan = 1, AppAmount = 0, PayAmount = 0, ShoAmount = 0, BalAmount = 0, AppType = 2, 
                        SchoolYear = (lastTerm == null ? 0 : lastTerm.SchoolYear), Term = (lastTerm == null ? 0 : lastTerm.Term), HolType = holType, Verify = 0, SchoolMark = schoolMark };
                    var t1 = new t_Amount { FYear = year, FMonth = month, FPlan = 1, AppAmount = 0, PayAmount = 0, ShoAmount = 0, BalAmount = 0, AppType = 1, 
                        SchoolYear = (lastTerm == null ? 0 : lastTerm.SchoolYear), Term = (lastTerm == null ? 0 : lastTerm.Term), HolType = holType, Verify = 0, SchoolMark = schoolMark };
                    var t2 = new t_Amount
                    {
                        FYear = year,
                        FMonth = month,
                        FPlan = 1,
                        AppAmount = 0,
                        PayAmount = 0,
                        ShoAmount = 0,
                        BalAmount = 0,
                        AppType = 3,
                        SchoolYear = (lastTerm == null ? 0 : lastTerm.SchoolYear),
                        Term = (lastTerm == null ? 0 : lastTerm.Term),
                        HolType = holType,
                        Verify = 0,
                        SchoolMark = schoolMark
                    };
                    db.AddTot_Amount(t0);
                    db.AddTot_Amount(t1);
                    db.AddTot_Amount(t2);

                    var arList = (from al in db.t_TeacherType select al).ToList<t_TeacherType>();
                    foreach (t_TeacherType tTeacherType in arList)
                    {
                        var a0 = new t_AccountingRules { FYear = year, FMonth = month, ActualWorkload = 1, Attendance = 1, Safety = 1, DeductAtt = 1, DeductSaf = 1, SubsidyCls = 1, ObjectRules = 0, SchoolMark = schoolMark };
                        switch (tTeacherType.FType) 
                        {
                            case 1:
                                a0 = new t_AccountingRules { FYear = year, FMonth = month, ActualWorkload = 1, Attendance = 1, Safety = 1, DeductAtt = 1, DeductSaf = 1, SubsidyCls = 0, ObjectRules = tTeacherType.RID, SchoolMark = schoolMark };
                                break;
                            case 2:
                                a0 = new t_AccountingRules { FYear = year, FMonth = month, ActualWorkload = 1, Attendance = 1, Safety = 1, DeductAtt = 1, DeductSaf = 1, SubsidyCls = 1, ObjectRules = tTeacherType.RID, SchoolMark = schoolMark };
                                break;
                            case 3:
                                a0 = new t_AccountingRules { FYear = year, FMonth = month, ActualWorkload = 1, Attendance = 1, Safety = 1, DeductAtt = 1, DeductSaf = 1, SubsidyCls = 1, ObjectRules = tTeacherType.RID, SchoolMark = schoolMark };
                                break;
                        }
                        db.AddTot_AccountingRules(a0);
                    }
                }
                else
                {
                    newAmount.FPlan = 1;
                    newAmount.HolType = holType;
                    db.t_Amount.ApplyCurrentValues(newAmount);

                    newAmount = list.FirstOrDefault(p => p.AppType == 2);
                    newAmount.FPlan = 1;
                    newAmount.HolType = holType;
                    db.t_Amount.ApplyCurrentValues(newAmount);
                }

                try
                {
                    db.SaveChanges();
                }
                catch (Exception)
                {
                    return false;
                }

                return true;
            }
        }

        /// <summary>
        /// 获取有数据的年份列表
        /// </summary>
        /// <param name="schoolMark">schoolMark</param>
        /// <returns></returns>
        public IList<int> GetYears(string schoolMark)
        {
            DBEntities db;
            using (db = new DBEntities())
            {
                var list = (from a in db.t_Amount
                            where a.SchoolMark == schoolMark
                            orderby a.FYear descending
                            select a.FYear).Distinct();

                var res = list.ToList();
                return (res.Where(re => re.HasValue).Select(re => re.Value)).ToList();
            }
        }

        /// <summary>
        /// 获取所有审核月
        /// </summary>
        /// <param name="schoolMark">schoolMark</param>
        /// <param name="isHolDay">是否假期</param>
        /// <returns></returns>
        public IList<string> GetAmountMonth(string schoolMark, int isHolDay)
        {
            DBEntities db;
            using (db = new DBEntities())
            {
                var list = (from am in db.t_Amount
                            where am.SchoolMark == schoolMark && am.HolType == isHolDay && am.AppType == 2
                            orderby am.FYear, am.FMonth ascending
                            select new
                            {
                                Year = am.FYear,
                                Month = am.FMonth
                            });

                var res = list.ToList();
                IList<string> dtList = new List<string>();
                foreach (var re in res)
                {
                    dtList.Add(string.Format("{0}-{1}", re.Year, re.Month));
                }
                return dtList;
            }
        }

        /// <summary>
        /// 获取指定年的拨款明细
        /// </summary>
        /// <param name="year">年份</param>
        /// <param name="schoolMark">schoolMark</param>
        /// <returns></returns>
        public IList<object> GetAmountsInYear(int year, string schoolMark)
        {
            DBEntities db;
            using (db = new DBEntities())
            {
                var list0 = (from a in db.t_Amount
                             where a.SchoolMark == schoolMark && a.FYear == year && a.AppType == 2
                             orderby a.FMonth ascending
                             select a);

                var list2 = (from a in db.t_Amount
                             where a.SchoolMark == schoolMark && a.FYear == year && a.AppType == 3
                             orderby a.FMonth ascending
                             select a);

                var list1 = (from a in db.t_Amount
                             where a.SchoolMark == schoolMark && a.FYear == year && a.AppType == 1
                             orderby a.FMonth ascending
                             select new
                             {
                                 Month = a.FMonth,
                                 AppAmount0 = list0.FirstOrDefault(p => p.FMonth == a.FMonth) == null ? 0 : list0.FirstOrDefault(p => p.FMonth == a.FMonth).AppAmount.HasValue ? list0.FirstOrDefault(p => p.FMonth == a.FMonth).AppAmount.Value : 0,
                                 AppAmount2 = list2.FirstOrDefault(p => p.FMonth == a.FMonth) == null ? 0 : list2.FirstOrDefault(p => p.FMonth == a.FMonth).AppAmount.HasValue ? list2.FirstOrDefault(p => p.FMonth == a.FMonth).AppAmount.Value : 0,
                                 AppAmount1 = a.AppAmount.HasValue ? a.AppAmount.Value : 0
                             });

                return list1.ToList<object>();
            }
        }

        /// <summary>
        /// 核算
        /// </summary>
        /// <param name="year">年</param>
        /// <param name="month">月</param>
        /// <param name="schoolmark">schoolMark</param>
        /// <param name="msg">提示信息</param>
        /// <returns></returns>
        public bool CalculatingInDate(int year, int month, String schoolmark, ref string msg)
        {
            DBEntities db;
            using (db = new DBEntities())
            {
                try
                {
                    db.Connection.CreateConnectionScope();
                    SqlParameter p1 = new SqlParameter("@fyear", SqlDbType.Int);
                    p1.Value = year;
                    p1.Direction = ParameterDirection.Input;

                    SqlParameter p2 = new SqlParameter("@fmonth", SqlDbType.Int);
                    p2.Direction = ParameterDirection.Input;
                    p2.Value = month;

                    SqlParameter p3 = new SqlParameter("@schoolMark", SqlDbType.NVarChar);
                    p3.Direction = ParameterDirection.Input;
                    p3.Value = schoolmark;

                    var cmd = db.CreateStoreCommand("P_CalculatingPays", CommandType.StoredProcedure, new object[] { p1, p2, p3 });

                    cmd.ExecuteNonQuery();
                }
                catch (Exception)
                {
                    msg += "\n核算失败";
                }
                return true;
            }
        }

        /// <summary>
        /// 审核
        /// </summary>
        /// <param name="year">年</param>
        /// <param name="month">月</param>
        /// <param name="schoolmark">schoolMark</param>
        /// <param name="msg">提示信息</param>
        /// <returns></returns>
        public bool AccountingInDate(int year, int month, String schoolmark, ref string msg)
        {
            DBEntities db;
            using (db = new DBEntities())
            {
                try
                {
                    var res = (from a in db.t_Amount
                               where a.FYear == year && a.FMonth == month && a.SchoolMark == schoolmark
                               select a).ToList();
                    foreach (t_Amount tAmount in res)
                    {
                        tAmount.Verify = 1;
                        db.t_Amount.ApplyCurrentValues(tAmount);
                    }
                    db.SaveChanges();
                }
                catch (Exception)
                {
                    msg += "\n核算失败";
                    throw;
                }
                return true;
            }
        }

        public bool HaveAccountData(int year, int month, string schoolMark)
        {
            DBEntities db;
            using (db = new DBEntities())
            {
                var t = from b in db.t_MeritPay
                        where b.FYear == year && b.FMonth == month && b.SchoolMark == schoolMark
                        select b;
                return t.Count() > 0;
            }
        }


        public IList<t_MeritPay> GetAmountInfoByDate(int startAt, int step, int year, int month, string schoolMark, int teacherType, string teacherCode, ref int count, bool isAdmin, int userID)
        {
            DBEntities db;
            using (db = new DBEntities())
            {
                var list = (from m in db.t_MeritPay
                            where m.SchoolMark == schoolMark && 
                            m.FYear == year && 
                            m.FMonth == month && 
                            ((teacherType == 0) ? m.TeachType != 3 : m.TeachType == 3) &&
                            (String.IsNullOrEmpty(teacherCode) ? true : (m.TeachCode.Contains(teacherCode) || m.TeachName.Contains(teacherCode))) &&
                            (isAdmin ? true : (m.TeacherID == userID))
                            orderby m.TeacherID
                            select m);
                count = list.Count();
                //if(count < 1)

                return list.Skip(startAt).Take(step).ToList<t_MeritPay>();
            }
        }
    }
}
